package com.easy.base.api.config.swagger;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;

import com.easy.base.api.model.dto.ResultBody;
import com.fasterxml.classmate.TypeResolver;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;

import io.swagger.annotations.ApiOperation;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.builders.ResponseBuilder;
import springfox.documentation.oas.annotations.EnableOpenApi;
import springfox.documentation.schema.QualifiedModelName;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Response;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;

@Configuration
@EnableOpenApi
public class SwaggerConfig {
	@Resource
	private TypeResolver typeResolver;

	@Bean
	public Docket baseApi() {
		return new Docket(DocumentationType.OAS_30)
				.apiInfo(apiInfo())
				.select() // 返回 ApiSelectorBuilder 的一个实例，以对通过 swagger 公开的端点进行细粒度控制。
				.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)) // 允许使用谓词选择 RequestHandler。
				.paths(PathSelectors.any())
				.build()
				.pathMapping("/") // 当 servlet 具有路径映射时，添加 servlet 路径映射。这使用提供的路径映射为路径添加前缀。
				.useDefaultResponseMessages(false) // 指示是否需要使用默认 http 响应代码的标志。
				.globalResponses(HttpMethod.GET, globalResponses())
				.globalResponses(HttpMethod.POST, globalResponses())
				.globalResponses(HttpMethod.PUT, globalResponses())
				.globalResponses(HttpMethod.DELETE, globalResponses())
				.additionalModels(typeResolver.resolve(ResultBody.class))
				.directModelSubstitute(Timestamp.class, String.class);
	}

	private ApiInfo apiInfo() {
		return new ApiInfoBuilder()
				.title("Base Api Project接口文档")
				.description("Base Api Project API")
				// .contact(new Contact("name", "个人主页url", "email")) //作者信息
				.version("0.0.1")
				.build();
	}

	private List<Response> globalResponses() {
		List<Response> list = new ArrayList<>();
		list.add(new ResponseBuilder()
				.code("404")
				.representation(MediaType.APPLICATION_JSON)
				.apply(r -> r.model(
						m -> m.referenceModel(
								ref -> ref.key(
										k -> k.qualifiedModelName(
												new QualifiedModelName("com.easy.base.api.model.dto", "ResultBody"))))))
				.build());
		list.add(new ResponseBuilder()
				.code("500")
				.representation(MediaType.APPLICATION_JSON)
				.apply(r -> r.model(
						m -> m.referenceModel(
								ref -> ref.key(
										k -> k.qualifiedModelName(
												new QualifiedModelName("com.easy.base.api.model.dto", "ResultBody"))))))
				.build());
		return list;
	}
}
